import {} from 'react-router-dom';

import { useEffect, useRef, useState } from 'react';

// 定义一个类型
type Channel = {
  id: number;
  name: string;
};

function App1() {
  //

  // 页面组件容器变量（获取dom，赋值给的变量）
  const inputRef = useRef<HTMLDivElement>(null);

  // 页面状态-数据
  const [name, setName] = useState<string>('Jack');
  // 页面状态-不指定-TS自动推导
  const [age, setAge] = useState(18);
  // 数组
  const [numArr, setNumArr] = useState([1, 2, 3]);
  // 对象
  const [obj, setObj] = useState({ name: 'Jack', age: 18 });
  // 明确指定对象类型
  const [obj2, setObj2] = useState<{ name: string; run: () => void }>({
    name: 'Jack',
    run: () => console.log('run'),
  });
  // 数组对象
  const [objArr, setObjArr] = useState([{ id: 1, name: 'React' }]);
  // 数组对象
  const [objArr2, setObjArr2] = useState<Channel[]>([]);

  // 组件渲染完毕后，执行某个操作：获取数据，给页面添加全局事件。
  useEffect(() => {
    // 给页面添加resize事件
    console.log('页面渲染完毕');
    const resize = () => console.log('页面大小发生变化了');
    window.addEventListener('resize', resize);
    // 返回 清理函数 destructor
    return () => {
      console.log('清理函数');
      window.removeEventListener('resize', resize);
    };
  }, []);

  // 事件
  const handleClick = () => {
    // 使用原生的dom
    // console.log(inputRef.current.value);  // 类型检查会报错，你没有处理null的情况
    // 1 && 操作符
    // console.log(inputRef.current && inputRef.current.value);
    // 2 三元表达式
    // console.log(inputRef.current ? inputRef.current.value : '');
    // 3 条件判断
    // if(!inputRef.current) return
    // console.log(inputRef.current.value)
    // 条件判断实现类型收缩,举例
    // function fn(x: number | string): void {
    //   if (typeof x === 'number') {
    //     // 鼠标放在 x 上查看类型为：
    //     console.log(x);
    //   } else if (typeof x === 'string') {
    //     // 此时，x 的类型为：
    //     console.log(x.length);
    //   } else {
    //     // 此时，x 的类型为：never
    //     console.log(x);
    //   }
    // }
    // 4 可选链操作符
    // console.log('===', inputRef.current?.innerText);
    // 5 非空断言
    // console.log('非空断言', inputRef.current!.innerText);

    // x的类型是一个对象，包含一个obj属性，obj要不为空，要不是一个包含一个类型是字符串的a属性
    let x: { obj: { a: string } | null };
    // 运行过程中值设置为null了。
    x = { obj: null };

    // 不确定运行中obj是否被赋值为null
    console.log('不报错', x.obj?.a);
    // 我确定obj一定不会为null，直接访问a属性
    console.log('太自信', x.obj!.a);

    // never
    // 1
    // let fn = () => {
    //   // 手动通过 throw 抛出一个异常（错误）
    //   throw new Error('err...');
    //   // 代码无法到达
    //   console.log('我无法到达');
    // };
    // let n = fn(); // n => never
    // 2
    // let fn = () => {
    //   while (true) {}
    //   console.log('我无法到达');
    // };
    // let n = fn(); // n => never
    // 3
    // const num = 123;
    // if (num !== 123) {
    //   let n = num; // n => never
    // }
    // 定义一个对象类型，属性随便
    // let obj1: {} = {};
    // obj1 = { a: 'a' };
    // // 和上面等价
    // let obj2: object = { b: 'b' };
    // obj2 = { c: 123 };
    // // 对比数据
    // let arr1: [] = []; // 只能为空的一个数组
    // // 包含任意元素类型的数组
    // let arr3: Array<any> = [];
    // let arr4: any[] = [];
    // console.log(objArr2);
    // setObjArr2([{ id: 1, name: 'html' }]);
    // setName('123');
    // setAge(23);
    // setNumArr([2, 3]);
    // setObj({ name: 'Rose', age: 19 });
    // setObjArr([{ id: 1, name: 'Vue' }]);
  };

  return (
    <div>
      <h1>App</h1>
      <div>{name}</div>
      <input type={'text'}></input>
      <div ref={inputRef}>divxxx</div>
      <br />
      <button onClick={handleClick}>按钮</button>
    </div>
  );
}

export default App1;
